#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

#include <pthread.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

static snd_pcm_t *handle = 0;	//PCI设备句柄
static snd_pcm_uframes_t frames;
char *buffer = 0;

#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int port = 6789;

int main(int argc, char *argv[])
{
	int rc;
	int ret;
	int size;
	snd_pcm_hw_params_t *params;	//硬件信息和PCM流配置
	unsigned int val;

	int dir = 0;
	int channels = 1;
	int frequency = 8000;
	int bit = 8;
	int datablock = 1;
	unsigned char ch[100];	//用来存储wav文件的头信息
	pthread_attr_t attr;	// 线程属性
	struct sched_param sched;	// 调度策略
	int t1, t2;
	
	int sin_len;
	char message[256];

	int socket_descriptor;
	struct sockaddr_in sin;
	int i = 0;
	pthread_t tid1;
	printf("carete getmuisc\n");

	pthread_attr_init(&attr);
	pthread_attr_setschedpolicy(&attr, SCHED_RR);

	rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
	if (rc < 0) {
		perror("\nopen PCM device failed:");
		exit(1);
	}

	snd_pcm_hw_params_alloca(&params);	//分配params结构体
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params_alloca:");
		exit(1);
	}
	rc = snd_pcm_hw_params_any(handle, params);	//初始化params
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params_any:");
		exit(1);
	}
	rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);	//初始化访问权限
	if (rc < 0) {
		perror("\nsed_pcm_hw_set_access:");
		exit(1);
	}
	//采样位数
	snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_U8);

	rc = snd_pcm_hw_params_set_channels(handle, params, channels);	//设置声道,1表示单声>道，2表示立体声
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params_set_channels:");
		exit(1);
	}
	val = frequency;
	rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);	//设置>频率
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params_set_rate_near:");
		exit(1);
	}

	rc = snd_pcm_hw_params(handle, params);
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params: ");
		exit(1);
	}

	rc = snd_pcm_hw_params_get_period_size(params, &frames, &dir);	/*获取周期长度 */
	if (rc < 0) {
		perror("\nsnd_pcm_hw_params_get_period_size:");
		exit(1);
	}
	snd_pcm_nonblock(handle, SND_PCM_NONBLOCK);

	size = frames * datablock;	/*4 代表数据快长度 */
	buffer = (char *)malloc(size);
	
	printf("Waiting for data form sender \n");

	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons(port);
	sin_len = sizeof(sin);

	socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
	bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin));
	while (1) {
		do 
		{
			i = recvfrom(socket_descriptor, buffer, 1024, 0, (struct sockaddr *)&sin, &sin_len);
		}while(i != 1024);
		// 写音频数据到PCM设备
		while (1) {
			ret = snd_pcm_writei(handle, buffer, frames);
			if (ret >= 0)
				break;
			usleep(2000);
			if (ret == -EPIPE) {
				fprintf(stderr, "underrun occurred\n");
				//完成硬件参数设置，使设备准备好 
				snd_pcm_prepare(handle);
			} else if (ret < 0) {
				fprintf(stderr, "error from writei: %s\n",
					snd_strerror(ret));
			}
		}
	}

	snd_pcm_drain(handle);
	snd_pcm_close(handle);
	free(buffer);
	return 0;
}
